package com.kinoshita.flow.service.impl;

import com.kinoshita.common.result.ResultDO;
import com.kinoshita.common.status.Constant;
import com.kinoshita.flow.api.domain.FlowInfoDO;
import com.kinoshita.flow.api.domain.LoanInitDO;
import com.kinoshita.flow.api.domain.LoanTaskDO;
import com.kinoshita.flow.api.domain.LoanTaskResultDO;
import com.kinoshita.flow.api.query.TaskQueryDO;
import com.kinoshita.flow.service.ILoanService;
import liquibase.pro.packaged.P;
import org.flowable.engine.*;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class LoanServiceImpl implements ILoanService {

    private static Logger logger = LoggerFactory.getLogger(LoanServiceImpl.class);

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private ProcessEngine processEngine;

    public ResultDO startFlow(LoanInitDO domain) {
        ResultDO resultDO = new ResultDO();
        Map<String, Object> param = new HashMap<>();
        param.put("applicant", domain.getApplyUser());
        param.put("manager", domain.getManagerUser());
        param.put("employee", domain.getEmployeeUser());
        ProcessInstance processInstance =
                runtimeService.startProcessInstanceByKey("loan-apply", param);
        String processId = processInstance.getProcessInstanceId();
        String name = processInstance.getName();
        FlowInfoDO flowInfoDO = new FlowInfoDO();
        flowInfoDO.setId(processId);
        flowInfoDO.setName(name);
        resultDO.setModel(Constant.DATA_MODEL_KEY, flowInfoDO);
        return resultDO;
    }

    public ResultDO queryTaskByUsername(TaskQueryDO queryDO) {
        ResultDO resultDO = new ResultDO();
        List<Task> list = taskService.createTaskQuery()
                .taskAssignee(queryDO.getUsername())
                .orderByTaskCreateTime()
                .desc()
                .list();
        List<LoanTaskResultDO> listDO = new ArrayList<>();
        for(Task task : list) {
            LoanTaskResultDO loanTaskResultDO = new LoanTaskResultDO();
            loanTaskResultDO.setId(task.getId());
            loanTaskResultDO.setName(task.getName());
            listDO.add(loanTaskResultDO);
        }
        resultDO.setModel(Constant.DATA_MODEL_KEY, listDO);
        return resultDO;
    }

    public ResultDO apply(LoanTaskDO domain) {
        ResultDO resultDO = new ResultDO();
        Task task = taskService.createTaskQuery()
                .taskId(domain.getId())
                .taskAssignee(domain.getUsername())
                .singleResult();
        if(task == null) {
            resultDO.setSuccess(false);
            return resultDO;
        }
        Map<String, Object> param = new HashMap<>();
        param.put("money", domain.getMoney());
        taskService.complete(task.getId(), param);
        return resultDO;
    }

    public ResultDO approval(LoanTaskDO domain) {
        ResultDO resultDO = new ResultDO();
        Task task = taskService.createTaskQuery()
                .taskId(domain.getId())
                .taskAssignee(domain.getUsername())
                .singleResult();
        if(task == null) {
            resultDO.setSuccess(false);
            return resultDO;
        }
        Map<String, Object> param = new HashMap<>();
        taskService.complete(task.getId());
        return resultDO;
    }

}
